Git jest dobrym wyborem jako system kontroli wersji. Żeby wygodnie go używać warto użyć usługi, która umożliwia hostowanie gitowych repozytoriów (projektów). Naturalnym wyborem jest Github.
Zadanie 1
Zarejestruj się na Githubie i stwórz repozytorium. Masz możliwość aplikowania o licencję studencką (m.in. darmowe prywatne repo).
Żeby skorzystać z Git trzeba go zainstalować.
Instrukcję można znaleźć tutaj.
¡Importante! Bez git nie ruszymy dalej. W razie trudności:
W przypadku gdyby ktoś wpadł w nieskończoną pętlę proszę o kontakt.
W praktyce, w większości przypadków możecie korzystać z Gita za pośrednictwem Waszego ulubionego IDE.
Dla R będzie to RStudio. Jeśli go nie macie to koniecznie zainstalujcie.
Jak widać możemy wygodnie (od lewej do prawej):
Pod spodem można dodać pliki.
Dalej jest interakcja z Githubem.
git init # tworzenei repo lokalnie
git pull # zmiany z serwera
git checkout -b new-branch # nowa gałąź
git add file1.R file2.py # staging plików
git commit -m 'commit message'
git push
Może się zdarzyć, że zmergowanie brancha nie jest możliwe, ponieważ występuje konflikt pomiędzy wersją naszą, a tą na serwerze. Najczęściej dlatego, że w międzyczasie ktoś inny wrzucił tam swoje zmiany. Wtedy te konflikty trzeba rozwiązać, dodać zmienione pliki.
git checkout -b new-branch # musimy być na nowej gałęzi
git merge master # próbujemy włączyć mastera
# rozwiazujemy konflikty lokalnie
git add conflict_file.py
git commit -m 'merging with master'
git push
Więcej na temat tego jak radzić sobie z branchami (gałęziami) można znaleźć tutaj.
Tak jak nie ma sensu pakować wszystkich swoich rzeczy na wakacje, tak nie należy pakować wszystkich lokalnych plików do git-owego repozytorium. W szczególności należy unikać dodawania dużych plików (w razie konieczności należy skorzystać z dedykowanego rozwiązania).
Aby utrzymać porządek i nie dodać przypadkowo ważnych plików należy umieścić informację o tym co nie jest potrzebne w pliku gitignore.
raw_data/ #wykluczenie całego folderu
!raw_data/include_me/* # ale umożliwamuy dodawanie pików w wybranym jego podfolderze
*.html #wykluczenie wszystkich plików html
raport*.* # wykluczenie plikow ze slowem raport w nazwie
Mamy dwie opcje:
git clone https://github.com/psobczyk/kurs_uam_2022.git
git remote -v # sprawdzamy jaki jest obecnie remote server
git remote add origin https://github.com/psobczyk/kurs_uam_2022.git
Jak zapewne zauważyliście na Githubie, klikając na klonowanie repozytorium mamy dwie opcje https i ssh. Pierwsza opcja oznacza, że wykonując wszelkie akcje na repozytorium będziemy się uwierzytelniać za pomocą loginu i hasła. Jest to dosyć niewygodne zwłaszcza przy dużej liczbie interakcji (i porządnym, długim haśle).
Druga opcja opiera się na użyciu kluczy gpg. Jest to bezpieczniejsza i wygodniejsza forma autoryzacji. W uproszczeniu: generuje się dwa klucze - prywatny i publiczny. Informację zakodowaną kluczem publicznym da się odczytać jedynie posiadając klucz prywatny. Klucz publiczny udostępnia się Githubowi, który jest dzięki temu w stanie sprawdzić czy my to rzeczywiście my (czyli czy posiadamy klucz prywatny).
Więcej na temat generowanie kluczy znajdziecie tutaj.
Proces dodawanie ich do konta jest opisany tutaj.
NIGDY
NIKOMU
NIE UDOSTĘPNIAMY
KLUCZA PRYWATNEGO
^^^ Podwójny gif pokazujący, że to jest naprawdę ważne.
Zadanie 2
Sprawdź, że masz dostęp do terminala na swoim komputerze i wywołaj kilka prostych gitowych komend.
Omawialiśmy różne opcje w R i w Pythonie. Ale skupmy się na tych rozwiązaniach, które są przeze mnie sugerowane. Nie musicie się zgadzać :)
Używamy renv. Kropka. Przy tworzeniu nowego projeku w RStudio możemy kliknąć, że chcemy użyć renv-a. Efektem jest utworzenie wirtualnego środowiska, czyli nie korzystamy z pakietów eRowych wcześniej zainstalowanych a mamy do dyspozycji coś co zachowuje się jak świeża, czysta instalacja eRa.
library(renv)
##
# Tutaj instalujemy potrzebne nam pakiety
##
renv::snapshot() # tworzy lock file (podobny do pythonowego Pipfile.lock)
# dalej rozwijamy projekt
# instalując kolejne pakiety
renv::restore() # jeśli coś przestało działać wracamy do ostatniej wersji
renv::snapshot() # jeśli wszystko działa to zapamię†ujemy ostatnie wersje pakietów
Dostajmy plik, który wygląda mniej więcej tak:
{
"R": {
"Version": "4.0.5",
"Repositories": [
{
"Name": "CRAN",
"URL": "https://cran.rstudio.com"
}
]
},
"Packages": {
"renv": {
"Package": "renv",
"Version": "0.13.2",
"Source": "Repository",
"Repository": "CRAN",
"Hash": "079cb1f03ff972b30401ed05623cbe92"
},
"rmarkdown": {
"Package": "rmarkdown",
"Version": "2.11",
"Source": "Repository",
"Repository": "CRAN",
"Hash": "320017b52d05a943981272b295750388"
}
}
}
Do systemu kontroli wersji wrzucamy:
Uwaga
renv wspiera nie tylko CRANa. Jest dostępny Bioconductor, można instalować pakiety prosto z Githuba. Należy dodać resztę folderu `renv`` do pliku .gitignore.
renv::init() # jesli nie zrobiło sie tego wcześniej
renv::restore()
Więcej informacji tutaj
Sugerowane podejście to użycie trójcy pip+venv+pip-tools.
Python domyślnie, w porównaniu z eRem, ma możliwość tworzenia wirtualnych środowisk (virtual environment). Jest to bardzo wygodna warstwa abstrakcji, która pozwala odizolować środowiska, w których działają poszczególne projekty. Dobre IDE domyślnie tworzą środowiska wirtualne dla nowych projektów. Jest to dobrą praktykę i nie należy robić inaczej.
Jeśli nie macie doświadczenia z wirtualnymi środowiskami to zachęcam mocno do przeczytania tego materiału.
.venv w naszym głownym folderze.python3.8 -m venv .venv
Tak jak pisałem wyżej, IDE może to zrobić na poziomie inicjalizacji projektu.
source .venv/bin/activate
Teraz w naszym terminalu Python będzie korzystać domyślnie z naszego wirtualnego środowiska. To jest cecha konkretnej otwartej konsoli a nie systemu. Nowo otwarta konsola nie będzie wskazywać na to środowisko wirtualne. Możemy sprawdzić jaka jest ścieżka pod którą Python będzie szukać bibliotek
echo $PATH
pip install -U pip setuptools wheel
pandas
numpy
sqlalchemy
pip-compile requirements.in
pip install -r requirements.txt
deactivate
Do gita wrzucamy dwa pliki:
Achtung!
Należy dodać folder .venv do pliku .gitignore.
Po ściągnięciu repozytorium, jeśli nie istnieje to tworzymy środowisko wirtualne, a potem instalujemy pakiety komendą
pip install -r requirements.txt
W praktyce występuje kilka problemów:
pip-compile jest nieprawidłowy i trzeba mu pomóc dodając dodatkowe ograniczenia w pliku requirements.in (porównaj tu i tu]).Czasami rozwiązanie drzewa zalezności wymaga ręcznych manipulacji. O różnych problemach na jakie można napotkać przeczytacie tutaj.
Dobre IDE mają oczywiście wsparcie dla Gita, ale nie oznacza to, że jesteśmy w stanie żyć zupełnie bez komend w terminalu. Samo ,,flow gitowe" czy stworzenie środowiska wirtualnego możemy tam zrobić. Ale rozwiązanie drzewa zależność, instalację pakietów z pliku requirements.txt robimy już z konsoli.
Zadanie 3